/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 *
 * @author: jin Chen 
 * @date: May 28, 2005$
 * @version: 1.0
 */
package edu.psu.geovista.app.hce.clustering.model;


import edu.psu.geovista.app.vit.pub.utils.VitUtils;
import edu.psu.geovista.common.utils.collection.CollectionUtils;

import javax.datamining.JDMException;
import javax.datamining.clustering.Cluster;
import java.util.*;

public class DfBCluster implements BCluster {
    private float similarity=Float.NaN ; //means no value assigned yet. It is to distinguish the sim=0 in real case
    private int index;//horizontal index
    private int[] Ids=new int[1];// 

     BCluster cls1;
     BCluster cls2;



     ClusterNode node;

    transient Vector attrVector;

    /**
     * get all observations' id belong to the cluster and to all its child clusters
     * @return
     */
    public int[] getIds() {
        return Ids;
    }

    public void setIds(int[] ids) {
        Ids = ids;
    }
    /**
     *  
     *  
     *  
     *
     * @return
     */
    public int[] computeIds(){
         //return null;  //calculate
        int[] Lids = cls1.computeIds();
        int[] Rids = cls2.computeIds();

        int[] ids = VitUtils.add(Lids,Rids);
        return ids;


    }

    /**
     *
     * @return
     * @throws javax.datamining.JDMException
     */
    public Cluster[] getChildren() throws JDMException {
        //todo generate from childrenSet
        return new Cluster[0];
    }

    public BCluster getCls1() {
        return cls1;
    }

    public void setCls1(BCluster cls1) {
        this.cls1 = cls1;
    }

    public BCluster getCls2() {
        return cls2;
    }

    public void setCls2(BCluster cls2) {
        this.cls2 = cls2;
    }

    public void setSimilarity(float similarity) {
        this.similarity = similarity;
    }

    public float getSimilarity() {
        return this.similarity;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public int getNumOfleaf() {
        return this.getIds().length ;
    }

 

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public Vector getAttrVector() {
        return attrVector;
    }

    public void setAttrVector(Vector attrVector) {
        this.attrVector = attrVector;
    }


   public Set getDataIndexSet(){
        Set rightIds = this.getRightDataIndexs();
        Set leftIds = this.getLeftDataIndexs();
        Set total=new HashSet(rightIds.size() +leftIds.size());
        if(rightIds!=null)
            total.addAll(rightIds);
        if(leftIds!=null)
            total.addAll(leftIds);

        return total;
    }

    public Cluster getJDMCluster() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public Set<Integer> getLeafIndexs(){
        Set<Integer> indexs=new HashSet<Integer>();
        List<LCluster> leafs = this.getLeafClusters();
        for (Iterator leafClusterIterator = leafs.iterator(); leafClusterIterator.hasNext();) {
            LCluster leaf = (LCluster) leafClusterIterator.next();
            indexs.add(leaf.getLfindex());
        }
        return indexs;
    }
     public Set getLeftDataIndexs() {
       // if(leftDataIndexs ==null){
            BCluster left = this.getCls1();
            if(left==null)return new HashSet();
            int[] ints = left.getIds();
         HashSet set=new HashSet();
         //if(ints!=null)
             set = CollectionUtils.convertArrayToSet(ints);
           
        return set;
        /*    leftDataIndexs = set;
        }
        return leftDataIndexs;*/
    }

    public Set getRightDataIndexs() {
        //if(rightDataIndexs ==null){
            BCluster right = this.getCls2();
            if(right ==null)return new HashSet();
            int[] ints = right.getIds();

            HashSet set =new HashSet();
        if(ints!=null)
        set=CollectionUtils.convertArrayToSet(ints);  //replaced by below 2008/02/19
            return set;

    }
     public  List<LCluster> getLeafClusters(){
        return getLeafClusters(this,null);
    }
    public static List<LCluster> getLeafClusters(BCluster cluster,List<LCluster> leafs){
    
        if (leafs==null) leafs=new ArrayList<LCluster>();
        if (cluster instanceof LCluster){//A leaf cluster
            leafs.add((LCluster) cluster);
        }
        else {//NOT a leaf cluster
            BCluster left = cluster.getCls1(); //
            getLeafClusters(left,leafs);   //always add left first
            BCluster right = cluster.getCls2();
            getLeafClusters(right,leafs);
        }
        return leafs;

    }
}

